﻿using System;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Diagnostics;
using MovieInfoSearchLib;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Threading;
using System.ComponentModel;

namespace MovieInfoView
{
	public partial class MovieSelect
	{

        Image imgHover = new Image();
        List<Movie> movies;

        

        public Movie SelectedMovie;

        public event EventHandler OnSelectionChanged;

        public event EventHandler OnFinishedLoading;

        public event EventHandler OnDownloadProgressChanged;

        private int total = 0;

		public MovieSelect()
		{
			this.InitializeComponent();
            img1.MouseUp += new System.Windows.Input.MouseButtonEventHandler(img1_MouseUp);
            img2.MouseUp += new System.Windows.Input.MouseButtonEventHandler(img2_MouseUp);
            img3.MouseUp += new System.Windows.Input.MouseButtonEventHandler(img3_MouseUp);
            img4.MouseUp += new System.Windows.Input.MouseButtonEventHandler(img4_MouseUp);
            img5.MouseUp += new System.Windows.Input.MouseButtonEventHandler(img5_MouseUp);
            img6.MouseUp += new System.Windows.Input.MouseButtonEventHandler(img6_MouseUp);
            img7.MouseUp += new System.Windows.Input.MouseButtonEventHandler(img7_MouseUp);
            img8.MouseUp += new System.Windows.Input.MouseButtonEventHandler(img8_MouseUp);
            img9.MouseUp += new System.Windows.Input.MouseButtonEventHandler(img9_MouseUp);
            img10.MouseUp += new System.Windows.Input.MouseButtonEventHandler(img10_MouseUp);
        }

        #region EventHandlers
        void img10_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(setSelection), 9);
        }

        void img9_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(setSelection), 8);
        }

        void img8_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(setSelection), 7);
        }

        void img7_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(setSelection), 6);
        }

        void img6_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(setSelection), 5);
        }

        void img5_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(setSelection), 4);
        }

        void img4_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(setSelection), 3);
        }

        void img3_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(setSelection), 2);
        }

        void img2_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(setSelection), 1);
        }

        void img1_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(setSelection), 0);
        }

        #endregion

        public void initData(List<Movie> movies)
        {
            this.movies = movies;

            ThreadStart start = delegate()
            {
                int total = movies.Count;
                if (total >= 10)
                {
                    total = 10;
                    while (movies.Count > 10)
                        movies.RemoveAt(10);
                }

                for (int i = 0; i < total; i++)
                {
                    Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int, System.Windows.Visibility>(setImgVisibility), i, System.Windows.Visibility.Visible);

                    Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(setImgInfo), i);

                    if (i == 0)
                        setSelection(0);
                }

                if(total < 10)
                    for (int i = total; i < 10; i++)
                    {
                        Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int, System.Windows.Visibility>(setImgVisibility), i, System.Windows.Visibility.Hidden);
                    }

                
            };
            new Thread(start).Start();
        }

        private void setImgVisibility(int img, System.Windows.Visibility vis)
        {
            ((Image)this.grdCovers.Children[img]).Visibility = vis;
        }


        public void clear()
        {
            movies.Clear();

            //loop through all of the MovieCover controls
            for (int i = 0; i < grdCovers.Children.Count; i++)
            {
                ((MovieCover)this.grdCovers.Children[i]).Source = null;
                ((MovieCover)this.grdCovers.Children[i]).ToolTip = null;
            }
        }
        private void setImgInfo(int img)
        {
            ((Image)this.grdCovers.Children[img]).ToolTip = movies[img].title + " (" + movies[img].releaseDate + ")";
            ((MovieCover)this.grdCovers.Children[img]).DownloadComplete += new EventHandler(MovieSelect_DownloadComplete);
            ((MovieCover)this.grdCovers.Children[img]).DownloadProgressChanged += new EventHandler(MovieSelect_DownloadProgressChanged);
            ((MovieCover)this.grdCovers.Children[img]).downloadImage(movies[img].imageURL);
        }

        void MovieSelect_DownloadProgressChanged(object sender, EventArgs e)
        {
            this.OnDownloadProgressChanged(this, new EventArgs());
        }

        void MovieSelect_DownloadComplete(object sender, EventArgs e)
        {
            bool allDownload = true;

            foreach (MovieCover cvr in this.grdCovers.Children)
            {
                if (cvr.IsVisible && !cvr.dlComplete)
                {
                    allDownload = false;
                    break;
                }
            }

            if (allDownload)
                this.OnFinishedLoading(this, new EventArgs());
        }

        public void setSelectedMovieImage()
        {
            for (int i = 0; i < grdCovers.Children.Count; i++)
            {
                if (((MovieCover)this.grdCovers.Children[i]).selected)
                {
                    this.SelectedMovie.image = ((MovieCover)this.grdCovers.Children[i]).getBitmapImage();
                    break;
                }
            }
        }

        public int getProgress()
        {
            int count = 0;
            foreach (MovieCover cvr in this.grdCovers.Children)
            {
                if (cvr.IsVisible)
                    count++;
            }
            int prog = 0;
            foreach (MovieCover cvr in this.grdCovers.Children)
            {
                if(cvr.IsVisible)
                    prog += cvr.dlProgress / count;
            }

            return prog;
        }

        /// <summary>
        /// Call the custom control function to select, or deselect, 
        /// every control when the selection is changed
        /// </summary>
        /// <param name="sel">The index of the currently selected movie.</param>
        private void clearSelection(int sel)
        {
            int maxCount = movies.Count;
            if (maxCount > grdCovers.Children.Count)
                maxCount = grdCovers.Children.Count;

            //loop through all of the MovieCover controls
            for (int i = 0; i < maxCount; i++)
            {
                //if this movie is not the new selection, make sure
                //that it's deselected.
                if (i != sel)
                    ((MovieCover)this.grdCovers.Children[i]).deSelect();

                // If this is the newly selected movie, the make
                //sure that it is selected
                else
                    ((MovieCover)this.grdCovers.Children[i]).setSelected();
            }
        }



        private void setSelection(int sel)
        {
            ThreadStart start = delegate()
            {
                Dispatcher.Invoke(DispatcherPriority.Normal,
                        new Action<int>(clearSelection), sel);

                
                if (!(sel >= movies.Count) &&
                    this.SelectedMovie != movies[sel])
                {
                    this.SelectedMovie = movies[sel];
                    this.OnSelectionChanged(this, null);
                }
            };
            new Thread(start).Start();
        }

    }
}